import 'dart:async';

import 'package:ble_helper_plugin/library.dart';
import 'package:bluetooth_protocols_parser_plugin/library.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:inmotion_pro/extension/future_error_handler.dart';
import 'package:inmotion_pro/http/api_helper_vehicle.dart';
import 'package:inmotion_pro/l10n/local.dart';
import 'package:inmotion_pro/pages/main/widgets/owner_info_view.dart';
import 'package:inmotion_pro/pages/main/widgets/sheet_vehicle_list_view.dart';
import 'package:inmotion_pro/pages/mixin/bluetooth_mixin.dart';
import 'package:inmotion_pro/pages/mixin/http_request_mixin.dart';
import 'package:inmotion_pro/pages/mixin/realtime_info_mixin.dart';
import 'package:inmotion_pro/pages/models/http_response/apply_owner_response_model.dart';
import 'package:inmotion_pro/pages/models/vehicle_model.dart';
import 'package:inmotion_pro/pages/main/constant/main_constant.dart';
import 'package:inmotion_pro/pages/main/widgets/set_user_region_view.dart';
import 'package:inmotion_pro/pages/mixin/cache_mixin.dart';
import 'package:inmotion_pro/pages/mixin/protocol_mixin.dart';
import 'package:inmotion_pro/pages/models/realtime_item.dart';
import 'package:inmotion_pro/service/global_service.dart';
import 'package:inmotion_pro/service/log_service.dart';
import 'package:inmotion_pro/service/realtime_data_server/realtime_data_service.dart';
import 'package:lx_widgets_library/lx_widgets_library.dart';

import '../../http/api_helper.dart';
import '../../service/vehicle_connection_service.dart';
import '../../service/cache_config_service.dart';
import '../../service/realtime_data_server/vehicle_realtime_data/vehicle_statistics_once.dart';
import '../../service/backend_service.dart';

class MainHelper
    with
        CacheMixin,
        ProtocolMixin,
        HttpRequestMixin,
        RealtimeInfoMixin,
        BluetoothMixin {
  // 创建一个回调，将单次统计数据回调出去
  Function(VehicleStatisticsOnce)? statisticsOnceCallback;

  /// MARK: 蓝牙连接成功后
  void afterConnectSuccessBusinessProcess() {
    if (!GlobalService.to.isLoggedIn) {
      // 游客模式下不执行该操作
      return;
    }
    List<Future> futures = [];
    // 1. 检查车辆是否可用
    futures.add(checkVehicleAvailable());
    // 2. 建立安全连接
    futures.add(buildSafeConnection().then((success) {
      if (success) {
        // 2.2. 清除强制升级状态
        return _clearForceUpgradeStatus().then((_) {
          // 无论成功与否，都继续后续操作
          return true;
        });
      }
      return Future.value();
    }));
    // 3. 调用单次统计数据接口 - 获取车辆上写入flash的单次统计数据
    futures.add(_getFlashLatestVehicleStatisticsOnce().then((statisticsOnce) {
      if (statisticsOnce != null && statisticsOnce.isValid) {
        statisticsOnceCallback?.call(statisticsOnce);
      }
      return Future.value();
    }));
    // 4. 上传车辆骑行记录
    futures.add(_uploadVehicleCyclingRecord());
    Future.wait(futures).catchErrorHandler();
  }

  // 1. 检查车辆是否可用，发送锁车指令，车辆会缓存该指令，等车辆静止后再执行锁车操作
  Future<bool> checkVehicleAvailable() {
    return ApiHelper()
        .checkVehicleAvailable(GlobalService.to.currentVehicleModel.value.sn)
        .then((available) {
      if (available) {
        debugPrint("✅ 服务端车辆可用状态：可用");
        return Future.value(true);
      } else {
        debugPrint("❌ 服务端车辆可用状态：不可用");
        return protocolMixinLock();
      }
    });
  }

  // 2. 建立安全连接
  Future<bool> buildSafeConnection() {
    if (VechileConnectionService.to.business == null) {
      debugPrint("❌ VechileConnectionService.to.business为空,无法建立安全连接");
      return Future.value(false);
    }
    if (CacheConfigService.to.isSecureConnection) {
      // 如果已经建立安全连接，则不需要再次建立
      debugPrint("✅ 已经建立安全连接");
      return Future(() => true);
    }
    // 检测车辆是否认证
    return VechileConnectionService.to.business!.buildSafeConnection().then((success) {
      return CacheConfigService.to
          .setSecureConnection(success)
          .then((_) => success);
    });
  }

  // 2.2. 清除强制升级的状态
  Future<bool> _clearForceUpgradeStatus() {
    return protocolMixinQueryForceFirmwareUpdateStatus().then((status) {
      debugPrint("✅ 检查强制升级状态完成，状态: $status");
      switch (status) {
        case FirmwareForceUpgradeStatus.limited:
          // 需要强制升级，则清除强制升级标记
          return protocolMixinClearForceFirmwareUpdateFlag().then((success) {
            if (success) {
              debugPrint("✅ 清除强制升级标记完成");
            } else {
              debugPrint("❌ 清除强制升级标记失败");
            }
            return success;
          });
        default:
          return true;
      }
    });
  }

  // 3. 获取车辆上写入flash的单次统计数据
  Future<VehicleStatisticsOnce?> _getFlashLatestVehicleStatisticsOnce() {
    return RealTimeDataService.to
        .getRealtimeStatisticsOnce(toUpdateGlobal: false)
        .then((rsp1) {
      if (rsp1 != null && rsp1.count > 1) {
        return RealTimeDataService.to.getRealtimeStatisticsOnce(
            toUpdateGlobal: false, startIndex: 1, count: 1);
      } else {
        return Future.value(null);
      }
    });
  }

  // 4. 上传车辆骑行记录
  Future<void> _uploadVehicleCyclingRecord() {
    // 开始上传车辆骑行记录
    return AppBackendService.to
        .start(types: [AppBackendService.to.busyCyclingRecordTimerType]);
  }

  // 设置服务器基础url
  Future<void> setBaseUrlByArea() {
    // 5.1 获取用户所属地区
    return _getUserRegion().then((area) {
      if (area.isNotEmpty) {
        debugPrint("✅ 设置服务器基础URL完成: $area");
      } else {
        // 5.3 - 当未设置所属地区时，则触发弹框，让用户选择地区
        showModalBottomSheet(
          isDismissible: false,
          enableDrag: false,
          isScrollControlled: true,
          backgroundColor: GrayColor.gray1,
          context: Get.context!,
          builder: (BuildContext context) {
            return SetUserRegionView(
              onSelected: (areaCodeModel, resultCallback) {
                Loading.showLoading(null);
                // 5.2 设置用户所属地区
                _setUserRegion(areaCodeModel.countryCode).then((success) {
                  if (success) {
                    // 5.1 获取用户所属地区，确认设置成功
                    _getUserRegion().then((area) {
                      if (area.isNotEmpty) {
                        Loading.showSuccess(local.setting_successful);
                      } else {
                        Loading.showError(local.setting_failed);
                      }
                    }).catchErrorHandler();
                  } else {
                    Loading.showError(local.setting_failed);
                  }
                  resultCallback(success);
                }).catchErrorHandler();
              },
            );
          },
        );
      }
      return Future.value();
    });
  }

  // 5.1 获取用户所属地区
  Future<String> _getUserRegion() {
    return ApiHelper().getUserRegion().then((area) {
      if (area.isNotEmpty) {
        debugPrint("✅ 获取用户所属地区 : $area");
        ApiHelper().setBaseUrlUserByArea(area);
        return Future.value(area);
      } else {
        debugPrint("❌ 用户未设置所属地区");
        return Future.value("");
      }
    });
  }

  // 5.2 设置用户所属地区
  Future<bool> _setUserRegion(String region) {
    return ApiHelper().setUserRegion(region).then((success) {
      if (success) {
        debugPrint("✅ 设置用户所属地区成功 : $region");
      } else {
        debugPrint("❌ 设置用户所属地区失败 : $region");
      }
      return Future.value(success);
    });
  }

  // MARK: - 刷新缓存中的车辆实时数据
  Future<bool> refreshCacheVehicleRealTimeData(
    String bleName, {
    double? estimatedRemainingMileage,
    double? totalMileage,
    double? batteryPercent,
    Map<String, dynamic>? cyclingRecord,
  }) {
    return cacheMixinRefreshCacheVehicleRealtimeData(bleName).then((success) {
      List<RealtimeItemModel> realtimeItems =
          GlobalService.to.cacheRealtimeItems;
      return cacheMixinCacheMixinNewCacheVehicleRealtimeData(
        bleName,
        (realtimeItems.isEmpty
                ? MainConstant.totalRealtimeItemList
                : realtimeItems)
            .map((item) => item.toMap())
            .toList(),
        estimatedRemainingMileage: estimatedRemainingMileage,
        totalMileage: totalMileage,
        batteryPercent: batteryPercent,
        cyclingRecord: cyclingRecord,
      );
    });
  }

  // MARK: - 申请车主
  applyOwner() {
    final vehicleModel = GlobalService.to.currentVehicleModel.value;
    Loading.showLoading(null);
    ApiHelper()
        .applyOwnerAuth(vehicleModel.sn, vehicleModel.bleName)
        .then((rsp) {
      if (rsp.applyStatus == ApplyOwnerStatus.success) {
        // 重新刷新数据
        ApiHelper()
            .getAuthorizedVehicleList(sn: vehicleModel.sn)
            .then((vehicleList) async {
          // 刷新缓存车辆列表
          await cacheMixinAuthorizedVehicleWriteToCache(vehicleList);
          Loading.showSuccess(local.apply_owner_success);
        }).catchErrorHandler();
      } else {
        Loading.dismiss();
        if (rsp.ownerInfo == null) return;
        LxAlert.show(
          title: local.prompt_title,
          local.apply_co_owner_success,
          showCancel: false,
          confirmTitle: local.confirm,
          extendWidget:
              OwnerInfoView(model: rsp.ownerInfo!), // 副车主申请时，必定返回主车主信息
        );
      }
    }).catchErrorHandler();
  }

  // MARK: - 启用轮询云盒在线状态任务
  Future<bool> toggleTboxOnlineStatusPollingTask() async {
    // 轮询云盒在线状态的间隔（秒）
    final type = AppBackendService.to.tboxOnlineStatusTimerType;
    // 停止任务
    AppBackendService.to.disposeTimer(type.$1.tag);
    // 启动任务
    return AppBackendService.to.start(types: [type], immediate: true);
  }

  // MARK: - 蓝牙连接/断开事件
  bluetoothConnectOrDisconnect({
    required CustomBluetoothConnectState bluetoothConnectState,
    required Function(CustomBluetoothConnectState)
        bluetoothConnectStateCallback,
    required VoidCallback? connectVehicleCallback,
    required VoidCallback? disconnectVehicleCallback,
  }) async {
    debugPrint("蓝牙连接/断开事件");
    // 连接/断开蓝牙
    if (GlobalService.to.isLoggedIn) {
      if (bluetoothConnectState == CustomBluetoothConnectState.disconnected ||
          bluetoothConnectState == CustomBluetoothConnectState.idle) {
        if (connectVehicleCallback != null) {
          connectVehicleCallback();
        }
      } else {
        // 断开蓝牙
        bluetoothConnectState = CustomBluetoothConnectState.disconnected;
        if (disconnectVehicleCallback != null) {
          disconnectVehicleCallback();
        }
      }
    } else {
      // 游客模式
      switch (bluetoothConnectState) {
        case CustomBluetoothConnectState.connected:
          // 断开蓝牙
          bluetoothConnectStateCallback(
              CustomBluetoothConnectState.disconnected);
          break;
        case CustomBluetoothConnectState.disconnected:
          bluetoothConnectStateCallback(CustomBluetoothConnectState.connecting);
          Future.delayed(const Duration(seconds: 3), () {
            // 连接成功
            bluetoothConnectStateCallback(
                CustomBluetoothConnectState.connected);
          });
          break;
        case CustomBluetoothConnectState.connecting:
          debugPrint("正在连接蓝牙，不响应点击事件");
          break;
        default:
          break;
      }
    }
  }

  // MARK: - 切换车辆
  switchVehicle({
    required Function() disconnectAndSearchCallback,
    required Function(VehicleModel) changeVehicleCallback,
    bool isSimpleVersion = false, // 简易版，不带删除、搜索功能、只用于展示车辆列表
  }) {
    showModalBottomSheet(
      backgroundColor: GrayColor.gray1,
      enableDrag: true,
      isScrollControlled: true,
      context: Get.context!,
      builder: (BuildContext context) {
        return SheetVehicleListView(
            isSimpleVersion: isSimpleVersion,
            vehicleList: GlobalService.to.cacheVehicleList.toList(),
            selectOnTap: (model) async {
              LogService.to.info("【$runtimeType】切换车辆: ${model.toMap()}");
              // 关闭底部弹窗
              Get.back();
              realtimeInfoMixinStopLoopToGetVehicleRealTimeData().then((_) {
                return cacheMixinsetAllVehiclesUnselected();
              }).then((_) {
                return cacheMixinUpdateCacheVehicle(model.bleName,
                    isSelected: true);
              }).then((_) {
                return bluetoothMixinDisconnect();
              }).then((_) {
                // 重新搜索并连接目标设备
                changeVehicleCallback(model);
              }).catchErrorHandler();
            },
            searchOnTap: () {
              Get.back();
              disconnectAndSearchCallback();
            },
            cancelOnTap: () => Get.back());
      },
    );
  }

  // MARK: - 锁车/解锁事件
  lockVehicle(
    bool isLocked,
    List<(PollingTimerType, int)> currentPollingTypes,
    Function(bool) lockStateCallback,
  ) {
    Loading.showLoading(isLocked ? local.unlocking : local.locking);
    if (GlobalService.to.isLoggedIn) {
      realtimeInfoMixinStopLoopToGetVehicleRealTimeDataThenStart(
              pollingTypes: currentPollingTypes,
              action: () =>
                  isLocked ? protocolMixinUnlock() : protocolMixinLock())
          .then((success) {
        if (success) {
          lockStateCallback(!isLocked);
          if (success) {
            Loading.showSuccess(
                isLocked ? local.unlock_success : local.lock_success);
          } else {
            Loading.showError(
                isLocked ? local.unlock_failed : local.lock_failed);
          }
        } else {
          Loading.showError(local.fail);
        }
      }).catchErrorHandler();
    } else {
      Future.delayed(const Duration(seconds: 1), () {
        Loading.showSuccess(
            isLocked ? local.unlock_success : local.lock_success);
        lockStateCallback(!isLocked);
      });
    }
  }

  // MARK: - 按喇叭事件
  clickHorn(
    List<(PollingTimerType, int)> currentPollingTypes,
  ) {
    Loading.showLoading(null);
    if (GlobalService.to.isLoggedIn) {
      realtimeInfoMixinStopLoopToGetVehicleRealTimeDataThenStart(
          pollingTypes: currentPollingTypes,
          action: () => protocolMixinHorn()).then((success) {
        Loading.showSuccess(success ? local.successed : local.fail);
      }).catchErrorHandler();
    } else {
      Future.delayed(const Duration(seconds: 1), () {
        Loading.showSuccess(local.successed);
      });
    }
  }

  // MARK: - 灯光事件
  clickLight(
    List<(PollingTimerType, int)> currentPollingTypes, {
    required bool lowBeam,
    required bool highBeam,
  }) {
    Loading.showLoading(null);
    if (GlobalService.to.isLoggedIn) {
      realtimeInfoMixinStopLoopToGetVehicleRealTimeDataThenStart(
              pollingTypes: currentPollingTypes,
              action: () =>
                  protocolMixinLight(lowBeam: lowBeam, highBeam: highBeam))
          .then((success) {
        Loading.showSuccess(success ? local.successed : local.fail);
      }).catchErrorHandler();
    } else {
      Future.delayed(const Duration(seconds: 1), () {
        Loading.showSuccess(local.successed);
      });
    }
  }
}
